home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / mysql / scripts / mysqld_multi < prev    next >
Encoding:
Text File  |  2006-04-26  |  22.6 KB  |  833 lines

  1. #!/usr/bin/perl
  2.  
  3. use Getopt::Long;
  4. use POSIX qw(strftime);
  5.  
  6. $|=1;
  7. $VER="2.15";
  8.  
  9. $opt_config_file   = undef();
  10. $opt_example       = 0;
  11. $opt_help          = 0;
  12. $opt_log           = undef();
  13. $opt_mysqladmin    = "/usr/local/bin/mysqladmin";
  14. $opt_mysqld        = "/usr/local/libexec/mysqld";
  15. $opt_no_log        = 0;
  16. $opt_password      = undef();
  17. $opt_tcp_ip        = 0;
  18. $opt_user          = "root";
  19. $opt_version       = 0;
  20. $opt_silent        = 0;
  21. $opt_verbose       = 0;
  22.  
  23. my $my_print_defaults_exists= 1;
  24. my $logdir= undef();
  25.  
  26. my ($mysqld, $mysqladmin, $groupids, $homedir, $my_progname);
  27.  
  28. $homedir = $ENV{HOME};
  29. $my_progname = $0;
  30. $my_progname =~ s/.*[\/]//;
  31.  
  32. main();
  33.  
  34. ####
  35. #### main sub routine
  36. ####
  37.  
  38. sub main
  39. {
  40.   my $flag_exit= 0;
  41.  
  42.   if (!defined(my_which(my_print_defaults)))
  43.   {
  44.     # We can't throw out yet, since --version, --help, or --example may
  45.     # have been given
  46.     print "WARNING: my_print_defaults command not found.\n";
  47.     print "Please make sure you have this command available and\n";
  48.     print "in your path. The command is available from the latest\n";
  49.     print "MySQL distribution.\n";
  50.     $my_print_defaults_exists= 0;
  51.   }
  52.   if ($my_print_defaults_exists)
  53.   {
  54.     foreach my $arg (@ARGV)
  55.     {
  56.       if ($arg =~ m/^--config-file=(.*)/)
  57.       {
  58.     if (!length($1))
  59.     {
  60.       die "Option config-file requires an argument\n";
  61.     }
  62.     elsif (!( -e $1 && -r $1))
  63.     {
  64.       die "Option file '$1' doesn't exists, or is not readable\n";
  65.     }
  66.     else
  67.     {
  68.       $opt_config_file= $1;
  69.       if (!($opt_config_file =~ m/\//))
  70.       {
  71.         # No path. Use current working directory
  72.         $opt_config_file= "./" . $opt_config_file;
  73.       }
  74.     }
  75.       }
  76.     }
  77.     my $com= "my_print_defaults ";
  78.     $com.= "--config-file=$opt_config_file " if (defined($opt_config_file));
  79.     $com.= "mysqld_multi";
  80.     my @defops = `$com`;
  81.     chop @defops;
  82.     splice @ARGV, 0, 0, @defops;
  83.   }
  84.   if (!GetOptions("help","example","version","mysqld=s","mysqladmin=s",
  85.           "config-file=s","user=s","password=s","log=s","no-log",
  86.           "tcp-ip", "silent","verbose"))
  87.   {
  88.     $flag_exit= 1;
  89.   }
  90.   if (defined($opt_config_file) && !($opt_config_file =~ m/\//))
  91.   {
  92.     # No path. Use current working directory
  93.     $opt_config_file= "./" . $opt_config_file;
  94.   }
  95.   usage() if ($opt_help);
  96.  
  97.   if ($opt_verbose && $opt_silent)
  98.   {
  99.     print "Both --verbose and --silent has been given. Some of the warnings ";
  100.     print "will be disabled\nand some will be enabled.\n\n";
  101.   }
  102.  
  103.   init_log() if (!defined($opt_log));
  104.   $groupids = $ARGV[1];
  105.   if ($opt_version)
  106.   {
  107.     print "$my_progname version $VER by Jani Tolonen\n";
  108.     exit(0);
  109.   }
  110.   example() if ($opt_example);
  111.   if ($flag_exit)
  112.   {
  113.     print "Error with an option, see $my_progname --help for more info.\n";
  114.     exit(1);
  115.   }
  116.   if (!defined(my_which(my_print_defaults)))
  117.   {
  118.     print "ABORT: Can't find command 'my_print_defaults'.\n";
  119.     print "This command is available from the latest MySQL\n";
  120.     print "distribution. Please make sure you have the command\n";
  121.     print "in your PATH.\n";
  122.     exit(1);
  123.   }
  124.   usage() if (!defined($ARGV[0]) ||
  125.           (!($ARGV[0] =~ m/^start$/i) &&
  126.            !($ARGV[0] =~ m/^stop$/i) &&
  127.            !($ARGV[0] =~ m/^report$/i)));
  128.  
  129.   if (!$opt_no_log)
  130.   {
  131.     w2log("$my_progname log file version $VER; run: ",
  132.       "$opt_log", 1, 0);
  133.   }
  134.   else
  135.   {
  136.     print "$my_progname log file version $VER; run: ";
  137.     print strftime "%a %b %e %H:%M:%S %Y", localtime;
  138.     print "\n";
  139.   }
  140.   if ($ARGV[0] =~ m/^start$/i)
  141.   {
  142.     if (!defined(($mysqld= my_which($opt_mysqld))) && $opt_verbose)
  143.     {
  144.       print "WARNING: Couldn't find the default mysqld binary.\n";
  145.       print "Tried: $opt_mysqld\n";
  146.       print "This is OK, if you are using option \"mysqld=...\" in ";
  147.       print "groups [mysqldN] separately for each.\n\n";
  148.     }
  149.     start_mysqlds();
  150.   }
  151.   else
  152.   {
  153.     if (!defined(($mysqladmin= my_which($opt_mysqladmin))) && $opt_verbose)
  154.     {
  155.       print "WARNING: Couldn't find the default mysqladmin binary.\n";
  156.       print "Tried: $opt_mysqladmin\n";
  157.       print "This is OK, if you are using option \"mysqladmin=...\" in ";
  158.       print "groups [mysqldN] separately for each.\n\n";
  159.     }
  160.     if ($ARGV[0] =~ m/^report$/i)
  161.     {
  162.       report_mysqlds();
  163.     }
  164.     else
  165.     {
  166.       stop_mysqlds();
  167.     }
  168.   }
  169. }
  170.  
  171. ####
  172. #### Quote option argument. Add double quotes around the argument
  173. #### and escape the following: $, \, "
  174. #### This function is needed, because my_print_defaults drops possible
  175. #### quotes, single or double, from in front of an argument and from
  176. #### the end.
  177. ####
  178.  
  179. sub quote_opt_arg
  180. {
  181.   my ($option)= @_;
  182.  
  183.   if ($option =~ m/(\-\-[a-zA-Z0-9\_\-]+)=(.*)/)
  184.   {
  185.     $option= $1;
  186.     $arg= $2;
  187.     $arg=~ s/\\/\\\\/g; # Escape escape character first to avoid doubling.
  188.     $arg=~ s/\$/\\\$/g;
  189.     $arg=~ s/\"/\\\"/g;
  190.     $arg= "\"" . $arg . "\"";
  191.     $option= $option . "=" . $arg;
  192.   }
  193.   return $option;
  194. }
  195.  
  196. ####
  197. #### Init log file. Check for appropriate place for log file, in the following
  198. #### order my_print_defaults mysqld datadir, /usr/local/share, /var/log, /tmp
  199. ####
  200.  
  201. sub init_log
  202. {
  203.   if ($my_print_defaults_exists)
  204.   {
  205.     @mysqld_opts= `my_print_defaults mysqld`;
  206.     chomp @mysqld_opts;
  207.     foreach my $opt (@mysqld_opts)
  208.     {
  209.       if ($opt =~ m/^\-\-datadir[=](.*)/)
  210.       {
  211.         if (-d "$1" && -w "$1")
  212.         {
  213.       $logdir= $1;
  214.         }
  215.       }
  216.     }
  217.   }
  218.   if (!defined($logdir))
  219.   {
  220.     $logdir= "/usr/local/share" if (-d "/usr/local/share" && -w "/usr/local/share");
  221.   }
  222.   if (!defined($logdir))
  223.   {
  224.     # Log file was not specified and we could not log to a standard place,
  225.     # so log file be disabled for now.
  226.     if (!$opt_silent)
  227.     {
  228.       print "WARNING: Log file disabled. Maybe directory or file isn't writable?\n";
  229.     }
  230.     $opt_no_log= 1;
  231.   }
  232.   else
  233.   {
  234.     $opt_log= "$logdir/mysqld_multi.log";
  235.   }
  236. }
  237.  
  238. ####
  239. #### Report living and not running MySQL servers
  240. ####
  241.  
  242. sub report_mysqlds
  243. {
  244.   my (@groups, $com, $i, @options, $pec);
  245.  
  246.   print "Reporting MySQL servers\n";
  247.   if (!$opt_no_log)
  248.   {
  249.     w2log("\nReporting MySQL servers","$opt_log",0,0);
  250.   }
  251.   @groups = &find_groups($groupids);
  252.   for ($i = 0; defined($groups[$i]); $i++)
  253.   {
  254.     $com= get_mysqladmin_options($i, @groups);
  255.     $com.= " ping >> /dev/null 2>&1";
  256.     system($com);
  257.     $pec = $? >> 8;
  258.     if ($pec)
  259.     {
  260.       print "MySQL server from group: $groups[$i] is not running\n";
  261.       if (!$opt_no_log)
  262.       {
  263.     w2log("MySQL server from group: $groups[$i] is not running",
  264.           "$opt_log", 0, 0);
  265.       }
  266.     }
  267.     else
  268.     {
  269.       print "MySQL server from group: $groups[$i] is running\n";
  270.       if (!$opt_no_log)
  271.       {
  272.     w2log("MySQL server from group: $groups[$i] is running",
  273.           "$opt_log", 0, 0);
  274.       }
  275.     }
  276.   }
  277.   if (!$i)
  278.   {
  279.     print "No groups to be reported (check your GNRs)\n";
  280.     if (!$opt_no_log)
  281.     {
  282.       w2log("No groups to be reported (check your GNRs)", "$opt_log", 0, 0);
  283.     }
  284.   }
  285. }
  286.  
  287. ####
  288. #### start multiple servers
  289. ####
  290.  
  291. sub start_mysqlds()
  292. {
  293.   my (@groups, $com, $tmp, $i, @options, $j, $mysqld_found, $info_sent);
  294.  
  295.   if (!$opt_no_log)
  296.   {
  297.     w2log("\nStarting MySQL servers\n","$opt_log",0,0);
  298.   }
  299.   else
  300.   {
  301.     print "\nStarting MySQL servers\n";
  302.   }
  303.   @groups = &find_groups($groupids);
  304.   for ($i = 0; defined($groups[$i]); $i++)
  305.   {
  306.     $com = "my_print_defaults";
  307.     $com.= defined($opt_config_file) ? " --config-file=$opt_config_file" : "";
  308.     $com.= " $groups[$i]";
  309.     @options = `$com`;
  310.     chop @options;
  311.  
  312.     $mysqld_found= 1; # The default
  313.     $mysqld_found= 0 if (!length($mysqld));
  314.     $com= "$mysqld";
  315.     for ($j = 0, $tmp= ""; defined($options[$j]); $j++)
  316.     {
  317.       if ("--mysqladmin=" eq substr($options[$j], 0, 13))
  318.       {
  319.     # catch this and ignore
  320.       }
  321.       elsif ("--mysqld=" eq substr($options[$j], 0, 9))
  322.       {
  323.     $options[$j]=~ s/\-\-mysqld\=//;
  324.     $com= $options[$j];
  325.         $mysqld_found= 1;
  326.       }
  327.       else
  328.       {
  329.     $options[$j]= quote_opt_arg($options[$j]);
  330.     $tmp.= " $options[$j]";
  331.       }
  332.     }
  333.     if ($opt_verbose && $com =~ m/\/safe_mysqld$/ && !$info_sent)
  334.     {
  335.       print "WARNING: safe_mysqld is being used to start mysqld. In this case you ";
  336.       print "may need to pass\n\"ledir=...\" under groups [mysqldN] to ";
  337.       print "safe_mysqld in order to find the actual mysqld binary.\n";
  338.       print "ledir (library executable directory) should be the path to the ";
  339.       print "wanted mysqld binary.\n\n";
  340.       $info_sent= 1;
  341.     }
  342.     $com.= $tmp;
  343.     $com.= " >> $opt_log 2>&1" if (!$opt_no_log);
  344.     $com.= " &";
  345.     if (!$mysqld_found)
  346.     {
  347.       print "\n";
  348.       print "FATAL ERROR: Tried to start mysqld under group [$groups[$i]], ";
  349.       print "but no mysqld binary was found.\n";
  350.       print "Please add \"mysqld=...\" in group [mysqld_multi], or add it to ";
  351.       print "group [$groups[$i]] separately.\n";
  352.       exit(1);
  353.     }
  354.     system($com);
  355.   }
  356.   if (!$i && !$opt_no_log)
  357.   {
  358.     w2log("No MySQL servers to be started (check your GNRs)",
  359.       "$opt_log", 0, 0);
  360.   }
  361. }
  362.  
  363. ####
  364. #### stop multiple servers
  365. ####
  366.  
  367. sub stop_mysqlds()
  368. {
  369.   my (@groups, $com, $i, @options);
  370.  
  371.   if (!$opt_no_log)
  372.   {
  373.     w2log("\nStopping MySQL servers\n","$opt_log",0,0);
  374.   }
  375.   else
  376.   {
  377.     print "\nStopping MySQL servers\n";
  378.   }
  379.   @groups = &find_groups($groupids);
  380.   for ($i = 0; defined($groups[$i]); $i++)
  381.   {
  382.     $com= get_mysqladmin_options($i, @groups);
  383.     $com.= " shutdown";
  384.     $com.= " >> $opt_log 2>&1" if (!$opt_no_log);
  385.     $com.= " &";
  386.     system($com);
  387.   }
  388.   if (!$i && !$opt_no_log)
  389.   {
  390.     w2log("No MySQL servers to be stopped (check your GNRs)",
  391.       "$opt_log", 0, 0);
  392.   }
  393. }
  394.  
  395. ####
  396. #### Sub function for mysqladmin option parsing
  397. ####
  398.  
  399. sub get_mysqladmin_options
  400. {
  401.   my ($i, @groups)= @_;
  402.   my ($mysqladmin_found, $com, $tmp, $j);
  403.  
  404.   $com = "my_print_defaults";
  405.   $com.= defined($opt_config_file) ? " --config-file=$opt_config_file" : "";
  406.   $com.= " $groups[$i]";
  407.   @options = `$com`;
  408.   chop @options;
  409.  
  410.   $mysqladmin_found= 1; # The default
  411.   $mysqladmin_found= 0 if (!length($mysqladmin));
  412.   $com = "$mysqladmin";
  413.   $tmp = " -u $opt_user";
  414.   if (defined($opt_password)) {
  415.     my $pw= $opt_password;
  416.     # Protect single quotes in password
  417.     $pw =~ s/'/'"'"'/g;
  418.     $tmp.= " -p'$pw'";
  419.   }
  420.   $tmp.= $opt_tcp_ip ? " -h 127.0.0.1" : "";
  421.   for ($j = 0; defined($options[$j]); $j++)
  422.   {
  423.     if ("--mysqladmin=" eq substr($options[$j], 0, 13))
  424.     {
  425.       $options[$j]=~ s/\-\-mysqladmin\=//;
  426.       $com= $options[$j];
  427.       $mysqladmin_found= 1;
  428.     }
  429.     elsif ((($options[$j] =~ m/^(\-\-socket\=)(.*)$/) && !$opt_tcp_ip) ||
  430.        ($options[$j] =~ m/^(\-\-port\=)(.*)$/))
  431.     {
  432.       $tmp.= " $options[$j]";
  433.     }
  434.   }
  435.   if (!$mysqladmin_found)
  436.   {
  437.     print "\n";
  438.     print "FATAL ERROR: Tried to use mysqladmin in group [$groups[$i]], ";
  439.     print "but no mysqladmin binary was found.\n";
  440.     print "Please add \"mysqladmin=...\" in group [mysqld_multi], or ";
  441.     print "in group [$groups[$i]].\n";
  442.     exit(1);
  443.   }
  444.   $com.= $tmp;
  445.   return $com;
  446. }
  447.  
  448. ####
  449. #### Find groups. Takes the valid group numbers as an argument, parses
  450. #### them, puts them in the ascending order, removes duplicates and
  451. #### returns the wanted groups accordingly.
  452. ####
  453.  
  454. sub find_groups
  455. {
  456.   my ($raw_gids) = @_;
  457.   my (@groups, @data, @tmp, $line, $i, $k, @pre_gids, @gids, @tmp2,
  458.       $prev_value);
  459.  
  460.   # Read the lines from the config file to variable 'data'
  461.   if (defined($opt_config_file))
  462.   {
  463.     open(MY_CNF, "<$opt_config_file") && (@data=<MY_CNF>) && close(MY_CNF);
  464.   }
  465.   else
  466.   {
  467.     if (-f "/etc/my.cnf" && -r "/etc/my.cnf")
  468.     {
  469.       open(MY_CNF, "</etc/my.cnf") && (@tmp=<MY_CNF>) && close(MY_CNF);
  470.     }
  471.     for ($i = 0; ($line = shift @tmp); $i++)
  472.     {
  473.       $data[$i] = $line;
  474.     }
  475.     if (defined($ENV{MYSQL_HOME}) && -f "$ENV{MYSQL_HOME}/my.cnf" &&
  476.     -r "$ENV{MYSQL_HOME}/my.cnf")
  477.     {
  478.       open(MY_CNF, "<$ENV{MYSQL_HOME}/my.cnf") && (@tmp=<MY_CNF>) &&
  479.       close(MY_CNF);
  480.     }
  481.     for (; ($line = shift @tmp); $i++)
  482.     {
  483.       $data[$i] = $line;
  484.     }
  485.     if (-f "$homedir/.my.cnf" && -r "$homedir/.my.cnf")
  486.     {
  487.       open(MY_CNF, "<$homedir/.my.cnf") && (@tmp=<MY_CNF>) && close(MY_CNF);
  488.     }
  489.     for (; ($line = shift @tmp); $i++)
  490.     {
  491.       $data[$i] = $line;
  492.     }
  493.   }
  494.   chop @data;
  495.   # Make a list of the wanted group ids
  496.   if (defined($raw_gids))
  497.   {
  498.     @pre_gids = split(',', $raw_gids);
  499.   }
  500.   if (defined($raw_gids))
  501.   {
  502.     for ($i = 0, $j = 0; defined($pre_gids[$i]); $i++)
  503.     {
  504.       if ($pre_gids[$i] =~ m/^(\d+)$/)
  505.       {
  506.     $gids[$j] = $1;
  507.     $j++;
  508.       }
  509.       elsif ($pre_gids[$i] =~ m/^(\d+)(\-)(\d+)$/)
  510.       {
  511.     for ($k = $1; $k <= $3; $k++)
  512.     {
  513.       $gids[$j] = $k;
  514.       $j++;
  515.     }
  516.       }
  517.       else
  518.       {
  519.     print "ABORT: Bad GNR: $pre_gids[$i] See $my_progname --help\n";
  520.     exit(1);
  521.       }
  522.     }
  523.   }
  524.   # Sort the list of gids numerically in ascending order
  525.   @gids = sort {$a <=> $b} @gids;
  526.   # Remove non-positive integers and duplicates
  527.   for ($i = 0, $j = 0; defined($gids[$i]); $i++)
  528.   {
  529.     next if ($gids[$i] <= 0);
  530.     if (!$i || $prev_value != $gids[$i])
  531.     {
  532.       $tmp2[$j] = $gids[$i];
  533.       $j++;
  534.     }
  535.     $prev_value = $gids[$i];
  536.   }
  537.   @gids = @tmp2;
  538.   # Find and return the wanted groups
  539.   for ($i = 0, $j = 0; defined($data[$i]); $i++)
  540.   {
  541.     if ($data[$i] =~ m/^(\s*\[\s*)(mysqld)(\d+)(\s*\]\s*)$/)
  542.     {
  543.       if (defined($raw_gids))
  544.       {
  545.     for ($k = 0; defined($gids[$k]); $k++)
  546.     {
  547.       if ($gids[$k] == $3)
  548.       {
  549.         $groups[$j] = $2 . $3;
  550.         $j++;
  551.       }
  552.     }
  553.       }
  554.       else
  555.       {
  556.     $groups[$j] = $2 . $3;
  557.     $j++;
  558.       }
  559.     }
  560.   }
  561.   return @groups;
  562. }
  563.  
  564. ####
  565. #### w2log: Write to a logfile.
  566. #### 1.arg: append to the log file (given string, or from a file. if a file,
  567. ####        file will be read from $opt_logdir)
  568. #### 2.arg: logfile -name (w2log assumes that the logfile is in $opt_logdir).
  569. #### 3.arg. 0 | 1, if true, print current date to the logfile. 3. arg will
  570. ####        be ignored, if 1. arg is a file.
  571. #### 4.arg. 0 | 1, if true, first argument is a file, else a string
  572. ####
  573.  
  574. sub w2log
  575. {
  576.   my ($msg, $file, $date_flag, $is_file)= @_;
  577.   my (@data);
  578.  
  579.   open (LOGFILE, ">>$opt_log")
  580.     or die "FATAL: w2log: Couldn't open log file: $opt_log\n";
  581.  
  582.   if ($is_file)
  583.   {
  584.     open (FROMFILE, "<$msg") && (@data=<FROMFILE>) &&
  585.       close(FROMFILE)
  586.     or die "FATAL: w2log: Couldn't open file: $msg\n";
  587.     foreach my $line (@data)
  588.     {
  589.       print LOGFILE "$line";
  590.     }
  591.   }
  592.   else
  593.   {
  594.     print LOGFILE "$msg";
  595.     print LOGFILE strftime "%a %b %e %H:%M:%S %Y", localtime if ($date_flag);
  596.     print LOGFILE "\n";
  597.   }
  598.   close (LOGFILE);
  599.   return;
  600. }
  601.  
  602. ####
  603. #### my_which is used, because we can't assume that every system has the
  604. #### which -command. my_which can take only one argument at a time.
  605. #### Return values: requested system command with the first found path,
  606. #### or undefined, if not found.
  607. ####
  608.  
  609. sub my_which
  610. {
  611.   my ($command) = @_;
  612.   my (@paths, $path);
  613.  
  614.   return $command if (-f $command && -x $command);
  615.   @paths = split(':', $ENV{'PATH'});
  616.   foreach $path (@paths)
  617.   {
  618.     $path .= "/$command";
  619.     return $path if (-f $path && -x $path);
  620.   }
  621.   return undef();
  622. }
  623.  
  624.  
  625. ####
  626. #### example
  627. ####
  628.  
  629. sub example
  630. {
  631.   print <<EOF;
  632. # This is an example of a my.cnf file for $my_progname.
  633. # Usually this file is located in home dir ~/.my.cnf or /etc/my.cnf
  634. #
  635. # SOME IMPORTANT NOTES FOLLOW:
  636. #
  637. # 1.COMMON USER
  638. #
  639. #   Make sure that the MySQL user, who is stopping the mysqld services, has
  640. #   the same password to all MySQL servers being accessed by $my_progname.
  641. #   This user needs to have the 'Shutdown_priv' -privilege, but for security
  642. #   reasons should have no other privileges. It is advised that you create a
  643. #   common 'multi_admin' user for all MySQL servers being controlled by
  644. #   $my_progname. Here is an example how to do it:
  645. #
  646. #   GRANT SHUTDOWN ON *.* TO multi_admin\@localhost IDENTIFIED BY 'password'
  647. #
  648. #   You will need to apply the above to all MySQL servers that are being
  649. #   controlled by $my_progname. 'multi_admin' will shutdown the servers
  650. #   using 'mysqladmin' -binary, when '$my_progname stop' is being called.
  651. #
  652. # 2.PID-FILE
  653. #
  654. #   If you are using mysqld_safe to start mysqld, make sure that every
  655. #   MySQL server has a separate pid-file. In order to use mysqld_safe
  656. #   via $my_progname, you need to use two options:
  657. #
  658. #   mysqld=/path/to/mysqld_safe
  659. #   ledir=/path/to/mysqld-binary/
  660. #
  661. #   ledir (library executable directory), is an option that only mysqld_safe
  662. #   accepts, so you will get an error if you try to pass it to mysqld directly.
  663. #   For this reason you might want to use the above options within [mysqld#]
  664. #   group directly.
  665. #
  666. # 3.DATA DIRECTORY
  667. #
  668. #   It is NOT advised to run many MySQL servers within the same data directory.
  669. #   You can do so, but please make sure to understand and deal with the
  670. #   underlying caveats. In short they are:
  671. #   - Speed penalty
  672. #   - Risk of table/data corruption
  673. #   - Data synchronising problems between the running servers
  674. #   - Heavily media (disk) bound
  675. #   - Relies on the system (external) file locking
  676. #   - Is not applicable with all table types. (Such as InnoDB)
  677. #     Trying so will end up with undesirable results.
  678. #
  679. # 4.TCP/IP Port
  680. #
  681. #   Every server requires one and it must be unique.
  682. #
  683. # 5.[mysqld#] Groups
  684. #
  685. #   In the example below the first and the fifth mysqld group was
  686. #   intentionally left out. You may have 'gaps' in the config file. This
  687. #   gives you more flexibility.
  688. #
  689. # 6.MySQL Server User
  690. #
  691. #   You can pass the user=... option inside [mysqld#] groups. This
  692. #   can be very handy in some cases, but then you need to run $my_progname
  693. #   as UNIX root.
  694. #
  695. # 7.A Start-up Manage Script for $my_progname
  696. #
  697. #   In the recent MySQL distributions you can find a file called
  698. #   mysqld_multi.server.sh. It is a wrapper for $my_progname. This can
  699. #   be used to start and stop multiple servers during boot and shutdown.
  700. #
  701. #   You can place the file in /etc/init.d/mysqld_multi.server.sh and
  702. #   make the needed symbolic links to it from various run levels
  703. #   (as per Linux/Unix standard). You may even replace the
  704. #   /etc/init.d/mysql.server script with it.
  705. #
  706. #   Before using, you must create a my.cnf file either in /etc/my.cnf
  707. #   or /root/.my.cnf and add the [mysqld_multi] and [mysqld#] groups.
  708. #
  709. #   The script can be found from support-files/mysqld_multi.server.sh
  710. #   in MySQL distribution. (Verify the script before using)
  711. #
  712.  
  713. [mysqld_multi]
  714. mysqld     = /usr/local/bin/mysqld_safe
  715. mysqladmin = /usr/local/bin/mysqladmin
  716. user       = multi_admin
  717. password   = my_password
  718.  
  719. [mysqld2]
  720. socket     = /tmp/mysql.sock2
  721. port       = 3307
  722. pid-file   = /usr/local/var2/hostname.pid2
  723. datadir    = /usr/local/var2
  724. language   = /usr/local/share/mysql/english
  725. user       = unix_user1
  726.  
  727. [mysqld3]
  728. mysqld     = /path/to/safe_mysqld/safe_mysqld
  729. ledir      = /path/to/mysqld-binary/
  730. mysqladmin = /path/to/mysqladmin/mysqladmin
  731. socket     = /tmp/mysql.sock3
  732. port       = 3308
  733. pid-file   = /usr/local/var3/hostname.pid3
  734. datadir    = /usr/local/var3
  735. language   = /usr/local/share/mysql/swedish
  736. user       = unix_user2
  737.  
  738. [mysqld4]
  739. socket     = /tmp/mysql.sock4
  740. port       = 3309
  741. pid-file   = /usr/local/var4/hostname.pid4
  742. datadir    = /usr/local/var4
  743. language   = /usr/local/share/mysql/estonia
  744. user       = unix_user3
  745.  
  746. [mysqld6]
  747. socket     = /tmp/mysql.sock6
  748. port       = 3311
  749. pid-file   = /usr/local/var6/hostname.pid6
  750. datadir    = /usr/local/var6
  751. language   = /usr/local/share/mysql/japanese
  752. user       = unix_user4
  753. EOF
  754.   exit(0);
  755. }
  756.  
  757. ####
  758. #### usage
  759. ####
  760.  
  761. sub usage
  762. {
  763.   print <<EOF;
  764. $my_progname version $VER by Jani Tolonen
  765.  
  766. Description:
  767. $my_progname can be used to start, or stop any number of separate
  768. mysqld processes running in different TCP/IP ports and UNIX sockets.
  769.  
  770. $my_progname can read group [mysqld_multi] from my.cnf file. You may
  771. want to put options mysqld=... and mysqladmin=... there.  Since
  772. version 2.10 these options can also be given under groups [mysqld#],
  773. which gives more control over different versions.  One can have the
  774. default mysqld and mysqladmin under group [mysqld_multi], but this is
  775. not mandatory. Please note that if mysqld or mysqladmin is missing
  776. from both [mysqld_multi] and [mysqld#], a group that is tried to be
  777. used, $my_progname will abort with an error.
  778.  
  779. $my_progname will search for groups named [mysqld#] from my.cnf (or
  780. the given --config-file=...), where '#' can be any positive integer
  781. starting from 1. These groups should be the same as the regular
  782. [mysqld] group, but with those port, socket and any other options
  783. that are to be used with each separate mysqld process. The number
  784. in the group name has another function; it can be used for starting,
  785. stopping, or reporting any specific mysqld server.
  786.  
  787. Usage: $my_progname [OPTIONS] {start|stop|report} [GNR,GNR,GNR...]
  788. or     $my_progname [OPTIONS] {start|stop|report} [GNR-GNR,GNR,GNR-GNR,...]
  789.  
  790. The GNR means the group number. You can start, stop or report any GNR,
  791. or several of them at the same time. (See --example) The GNRs list can
  792. be comma separated or a dash combined. The latter means that all the
  793. GNRs between GNR1-GNR2 will be affected. Without GNR argument all the
  794. groups found will either be started, stopped, or reported. Note that
  795. syntax for specifying GNRs must appear without spaces.
  796.  
  797. Options:
  798. --config-file=...  Alternative config file.
  799.                    Using: $opt_config_file
  800. --example          Give an example of a config file with extra information.
  801. --help             Print this help and exit.
  802. --log=...          Log file. Full path to and the name for the log file. NOTE:
  803.                    If the file exists, everything will be appended.
  804.                    Using: $opt_log
  805. --mysqladmin=...   mysqladmin binary to be used for a server shutdown.
  806.                    Since version 2.10 this can be given within groups [mysqld#]
  807.                    Using: $mysqladmin
  808. --mysqld=...       mysqld binary to be used. Note that you can give mysqld_safe
  809.                    to this option also. The options are passed to mysqld. Just
  810.                    make sure you have mysqld in your PATH or fix mysqld_safe.
  811.                    Using: $mysqld
  812.                    Please note: Since mysqld_multi version 2.3 you can also
  813.                    give this option inside groups [mysqld#] in ~/.my.cnf,
  814.                    where '#' stands for an integer (number) of the group in
  815.                    question. This will be recognised as a special option and
  816.                    will not be passed to the mysqld. This will allow one to
  817.                    start different mysqld versions with mysqld_multi.
  818. --no-log           Print to stdout instead of the log file. By default the log
  819.                    file is turned on.
  820. --password=...     Password for mysqladmin user.
  821. --silent           Disable warnings.
  822. --tcp-ip           Connect to the MySQL server(s) via the TCP/IP port instead
  823.                    of the UNIX socket. This affects stopping and reporting.
  824.                    If a socket file is missing, the server may still be
  825.                    running, but can be accessed only via the TCP/IP port.
  826.                    By default connecting is done via the UNIX socket.
  827. --user=...         mysqladmin user. Using: $opt_user
  828. --verbose          Be more verbose.
  829. --version          Print the version number and exit.
  830. EOF
  831.   exit(0);
  832. }
  833.